/*
 * EGSE.cpp
 *
 *  Created on: 03.06.2011
 *      Author: user
 */

#include "SatelliteInterface.h"
#include "worker-monitor-topics.h"
#include <vector>
#include <algorithm>
//#include <utility>

//static Application testingApplication("Random Name");


SatelliteInterface::SatelliteInterface():SatelitteSubscriber(nmx,SatelliteBuffer){
	maxPing = 4;
}

int SatelliteInterface::getNumNodes(){
	return nodelist.size();
}

int SatelliteInterface::getNumDisabledNodes(){
	return -1;
}

int SatelliteInterface::getNumResponsiveNodes() {
	int size = nodelist.size();
	int count = 0;
	for(int i = 0;i<size;i++){
		if(nodelist[i].second){
			count++;
		}
	}
	return count;
}

int* SatelliteInterface::getUnresponsiveNodes(){
	int size = nodelist.size();
	int count = 0;
	for(int i = 0;i<=size-1;i++){
		if(!nodelist[i].second){
			count++;
		}
	}

	int* result = new int[count];
	count = 0;
	for(int i = 0;i<=size-1;i++){
		if(!nodelist[i].second){
			result[i] = nodelist[count].first;
			count++;
		}
	}
	return result;
}

int* SatelliteInterface::getResponsiveNodes(){
	int size = nodelist.size();
	int count = 0;
	for(int i = 0;i<=size-1;i++){
		if(nodelist[i].second){
			count++;
		}
	}

	int* result = new int[count];
	count = 0;
	for(int i = 0;i<=size-1;i++){
		if(nodelist[i].second){
			result[i] = nodelist[count].first;
			count++;
		}
	}
	return result;
}

int* SatelliteInterface::getNodeIDList(){
//	PRINTF(SCREEN_MOVE_CURSOR_TO, 2, 1);
//	PRINTF("getNodeIDList \n");
	int size = (int)nodelist.size();

	int* result = new int[size];
//	PRINTF(SCREEN_MOVE_CURSOR_TO, 2, 20);
//	PRINTF("Size: %d\n",size);
	for(int i = 0;i<=size-1;i++){
    	std::pair<int,bool> p = nodelist[i];
    	if(p.second){
    		result[i] =  p.first;
    	}
    }
	return result;
}

int SatelliteInterface::getWorkerID(){
	return WorkerID;
}

void SatelliteInterface::setWorker(int ID){
	WMMessage output = {SetWorker,ID,1};
	for(int i = 0;i<3;i++){
		nmx.publish(output);
		WorkerPing();
	}
}

void SatelliteInterface::setMonitor(int ID){
	WMMessage output = {SetMonitor,ID,1};
	nmx.publish(output);
}

operationMode SatelliteInterface::getMode(){
	return oMode;
}

void SatelliteInterface::setMode(operationMode mode){
	WMMessage output = {SetMode,-1,-1};
	nmx.publish(output);
}

void SatelliteInterface::Ping(){
	WMMessage output = {PING,-1,-1};
	nmx.publish(output);
	int size = nodelist.size();
	if(PingCount == maxPing){
		for(int i = 0;i<=size-1;i++){
			nodelist[i].second = false;
		}
		PingCount = 0;
	}
	PingCount++;
}

void SatelliteInterface::WorkerPing(){
	WMMessage output = {identifyWorker,-1,-1};
	nmx.publish(output);
}

void SatelliteInterface::handleMessages(){
	WMMessage topicInput = {MEANINGLESS,-1,-1};
//	PRINTF("PingCount: %d maxPing: %d",PingCount,maxPing);
	while(SatelliteBuffer.get(topicInput)){
		if(topicInput.messageType == PONG){
			int size = ( nodelist.size());
			std::pair<int,bool> p(topicInput.nodeNumber,false);
			int pos = std::find(nodelist.begin(),nodelist.end(),p)-nodelist.begin();
			if(pos > (size-1)){
				p.second = true;
				pos = std::find(nodelist.begin(),nodelist.end(),p)-nodelist.begin();
			}
			if (pos > (size-1)){
				nodelist.push_back(p);
			}else{
				nodelist[pos].second = true;
			}
		}
		if(topicInput.messageType == identifyWorker && topicInput.nodeNumber != -1){
			WorkerID = topicInput.nodeNumber;
		}
	}
}

bool SatelliteInterface::putGeneric(const unsigned int len, const void* msg){
	bool result = false;
    WMMessage input = *(WMMessage*)msg;
    result = SatelliteBuffer.put(input);
    return result;
}

void SatelliteInterface::init(){

}

void SatelliteInterface::updateSatellite() {
	Ping();
	WorkerPing();
	handleMessages();
}
/*
void SatelliteInterface::run(){
	while(1){
		waitUntil(NOW()+1*SECONDS);
		Ping();
		WorkerPing();
		handleMessages();
/**
		PRINTF(SCREEN_CLEAR);
		int size = nodelist.size();
		PRINTF(SCREEN_MOVE_CURSOR_TO, 1, 1);
		PRINTF("NodeID");
		PRINTF(SCREEN_MOVE_CURSOR_TO, 1, 10);
		PRINTF("Enabled");

//		PRINTF(SCREEN_MOVE_CURSOR_TO, 3, 1);
//		PRINTF("Size: %d\n",size);
		for(int i=0;i<=size-1;i++){
			PRINTF(SCREEN_MOVE_CURSOR_TO, 2+i, 3);
			PRINTF("%d",nodelist[i].first);

			PRINTF(SCREEN_MOVE_CURSOR_TO, 2+i, 12);
			if(nodelist[i].second){
				PRINTF("true");
			}else PRINTF("false");

			PRINTF(SCREEN_MOVE_CURSOR_TO, 2+i, 21);
			if(nodelist[i].first == WorkerID){
				PRINTF("true");
			}
		}
//		getResponsiveNodes();
		PRINTF(SCREEN_MOVE_CURSOR_TO, 1, 20);
		PRINTF("Worker");
		PRINTF(SCREEN_MOVE_CURSOR_TO, 1, 30);
		PRINTF("Nodecount %d\n\n",(int) nodelist.size());
	}
}*/
